package com.managertrade.util;

import java.util.ArrayList;
import java.util.List;

public class IndicatorUtil {

    // 计算EMA（指数移动平均）
    public static List<Double> ema(List<Double> prices, int period) {
        List<Double> emaList = new ArrayList<>();
        if (prices == null || prices.size() == 0) return emaList;

        double multiplier = 2.0 / (period + 1);
        double ema = prices.get(0); // 第一个ema等于第一个收盘价

        emaList.add(ema);

        for (int i = 1; i < prices.size(); i++) {
            ema = (prices.get(i) - ema) * multiplier + ema;
            emaList.add(ema);
        }
        return emaList;
    }

    // MACD 计算结果封装类
    public static class MacdResult {
        public List<Double> macd;       // DIF线
        public List<Double> signal;     // DEA线
        public List<Double> histogram;  // MACD柱状图

        public MacdResult(List<Double> macd, List<Double> signal, List<Double> histogram) {
            this.macd = macd;
            this.signal = signal;
            this.histogram = histogram;
        }
    }

    // 计算MACD指标
    // fastPeriod = 12, slowPeriod = 26, signalPeriod = 9是经典参数
    public static MacdResult macd(List<Double> prices, int fastPeriod, int slowPeriod, int signalPeriod) {
        List<Double> emaFast = ema(prices, fastPeriod);
        List<Double> emaSlow = ema(prices, slowPeriod);
        List<Double> dif = new ArrayList<>();

        // 计算DIF线
        for (int i = 0; i < prices.size(); i++) {
            double fast = i < emaFast.size() ? emaFast.get(i) : 0;
            double slow = i < emaSlow.size() ? emaSlow.get(i) : 0;
            dif.add(fast - slow);
        }

        // 计算DEA线（DIF的EMA）
        List<Double> dea = ema(dif, signalPeriod);

        // 计算MACD柱状图 = 2 * (DIF - DEA)
        List<Double> macdHist = new ArrayList<>();
        for (int i = 0; i < dif.size(); i++) {
            double val = 2 * (dif.get(i) - (i < dea.size() ? dea.get(i) : 0));
            macdHist.add(val);
        }

        return new MacdResult(dif, dea, macdHist);
    }

    // BOLL 计算结果封装类
    public static class BollResult {
        public List<Double> upper;   // 上轨线
        public List<Double> middle;  // 中轨线（N日均线）
        public List<Double> lower;   // 下轨线

        public BollResult(List<Double> upper, List<Double> middle, List<Double> lower) {
            this.upper = upper;
            this.middle = middle;
            this.lower = lower;
        }
    }

    // 计算BOLL指标
    // period=20, k=2是常见参数
    public static BollResult boll(List<Double> prices, int period) {
        List<Double> middle = sma(prices, period);
        List<Double> upper = new ArrayList<>();
        List<Double> lower = new ArrayList<>();

        for (int i = 0; i < prices.size(); i++) {
            if (i < period - 1) {
                upper.add(null);
                lower.add(null);
            } else {
                double sumSquaredDiff = 0.0;
                for (int j = i - period + 1; j <= i; j++) {
                    double diff = prices.get(j) - middle.get(i);
                    sumSquaredDiff += diff * diff;
                }
                double stdDev = Math.sqrt(sumSquaredDiff / period);
                upper.add(middle.get(i) + 2 * stdDev);
                lower.add(middle.get(i) - 2 * stdDev);
            }
        }
        return new BollResult(upper, middle, lower);
    }

    // 计算简单移动平均（SMA）
    public static List<Double> sma(List<Double> prices, int period) {
        List<Double> smaList = new ArrayList<>();
        double sum = 0.0;
        for (int i = 0; i < prices.size(); i++) {
            sum += prices.get(i);
            if (i >= period) {
                sum -= prices.get(i - period);
                smaList.add(sum / period);
            } else if (i == period - 1) {
                smaList.add(sum / period);
            } else {
                smaList.add(null); // 不足period时，填充null
            }
        }
        return smaList;
    }
}

